package org.languageguide.readings;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.languageguide.storage.DBConnector;
import org.languageguide.user.User;
import org.languageguide.versioncontrol.LockingVersionControl;

/**
 * 
 * 
 * @author Tom Blackmon
 */


public class ReadingImpl implements LockingVersionControl, Reading{

	private String text;
	private String title;
	private String id;
	private String language;
	private String wordWrappedWithTranslations;
	private String sentenceWrappedReading;
	private String times;
	private String soundFilePath;
	private String status;
	private Integer highestIdProcessed;
	private String source;
	private String translatedTitle;
	//private Integer highestIdAdjusted;
	private String adjustedWordIds;
	//private String checkedWords;
	
	//private String userId;
	//private boolean checkedOut;
	private int wordCount;
//	private Time checkOutTime;
	boolean loaded = false;
	boolean hasWordGranularity = false;
	boolean isVideo = false;
	
	public ReadingImpl(String id){
		this.id  = id;
		loadReadingFromDb();
	}
	
	public String getId(){
		return id;
	}
	
	public ReadingImpl(ResultSet set) throws SQLException{
		processRow(set);
	}
		
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#setStatus(java.lang.String)
	 * text-submited
sound-submitted
sound-needed
roughly-sound-integrated
sound-integrated
published
	 */
	public void setStatus(String status){
		String sql = "Update Readings Set Status=\"" + status + "\" WHERE Id=" + id;
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			Statement statement = connection.createStatement();
			statement.executeUpdate(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		finally{
			connector.close(connection);
		}	
	}
	
	private void loadReadingFromDb(){
		loadReadingFromDb(null);
	}
	
	private void loadReadingFromDb(String userId){
		String sql_load = "SELECT * FROM Readings WHERE Readings.Id = " + id;
		System.out.println("sql_load:" + sql_load);
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			Statement statement = connection.createStatement();
			ResultSet set = statement.executeQuery(sql_load);
			if (set.next()){
				processRow(set);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			connector.close(connection);
		}
	}
	
	public boolean checkin(User user) {
		Integer userId = user.getIdInteger();
		String statement = "UPDATE Readings SET CheckedOut = 0 WHERE Id = ? AND EditingUserId = ?";
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		System.out.println("checkin called" + statement);
		try {
			PreparedStatement ps = connection.prepareStatement(statement);
			ps.setString(1, id);
			ps.setInt(2, userId);
			int rows = ps.executeUpdate();
			System.out.println("checking in");
			if (rows > 0){
				return true;
			}
			else return false;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			connector.close(connection);
		}

		return false;
	}

	
	public boolean checkout(User user) {
		Integer userId = user.getIdInteger();
			//			SELECT * From TranslatedReading  4
		String statement = "UPDATE Readings SET CheckedOut = 1, CheckoutTime = NULL, EditingUserId = ? WHERE Id = ? AND ((CheckedOut = 0 OR (DATE_ADD(CheckoutTime, INTERVAL 1 HOUR) < NOW())) OR EditingUserId = ?)";
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			PreparedStatement ps = connection.prepareStatement(statement);
			ps.setInt(1, userId);
			ps.setString(2, id);
			ps.setInt(3, userId);
			int rows = ps.executeUpdate();
			if (rows > 0)
				return true;
			else return false;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		finally{
			connector.close(connection);
		}
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getWordWrappedReading()
	 */
	public String getWordWrappedReading(){
		return wordWrappedWithTranslations;
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getTimes()
	 */
	public String getTimes(){
		if (times == null)
			return "";
		else {
			return times;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getTitle()
	 */
	public String getTitle(){
		//if (translatedTitle != null)
		//	return translatedTitle;
		return title;
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getWordCount()
	 */
	public Integer getWordCount(){
		return wordCount;
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getHighestIdProcessed()
	 */
	public Integer getHighestIdProcessed(){
		return highestIdProcessed;
	}
	/*
	public Integer getHighestIdAdjusted(){
		return highestIdAdjusted;
	}*/
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getAdjustedWordsIds()
	 */
	public String getAdjustedWordsIds(){
		if (adjustedWordIds == null){
			return "";
		}
		else{
			return adjustedWordIds;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getLanguage()
	 */
	public String getLanguage(){
		return language;
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getStatus()
	 */
	public String getStatus(){
		return status;
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getText()
	 */
	public String getText(){
		return text;
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getSoundPath()
	 */
	public String getSoundPath(){
		return soundFilePath;
	}
	
	public String getSource(){
		return source;
	}
	
	
	public boolean hasWordGranularity(){
		return hasWordGranularity;
	}
	
	/* (non-Javadoc)
	 * @see org.languageguide.readings.Reading#getSentenceWrappedReading()
	 */
	public String getSentenceWrappedReading(){
		return sentenceWrappedReading;
	}
	
	public String getWrappedReading(){
		if (hasWordGranularity){
			return wordWrappedWithTranslations;
		}
		else{
			return getSentenceWrappedReading(); 
		}
		
	}
	
	private void generateWordWrappedReading(String text){
		ReadingDivider divider = new ReadingDivider(text);
		WordWrapper reading = new StandardWordWrapper();
		String wordWrappedTextBody = reading.wrap(divider.getBody());
		wordWrappedWithTranslations = wordWrappedTextBody + divider.getTranslations(); 
		wordCount = reading.getWordCount();
	}
	
	public boolean isVideo(){
		return isVideo;
	}

	private void processRow(ResultSet set) throws SQLException{
		text = set.getString("Readings.Text");
		hasWordGranularity = set.getBoolean("Readings.HasWordGranularity");
		if (hasWordGranularity){
			wordWrappedWithTranslations = set.getString("Readings.WordWrappedText");
			if (wordWrappedWithTranslations == null){
				generateWordWrappedReading(text);
			}
			else{
				wordCount = set.getInt("Readings.WordCount");
			}
		}
		
		sentenceWrappedReading = set.getString("Readings.SentenceWrappedText");
		
		//wordWrappedW = set.getString("Readings.WordWrapped");
		id = set.getString("Readings.Id");
		title = set.getString("Readings.Title");
		//translatedTitle = set.getString("TranslatedReading.Title");
		language = set.getString("Readings.Language");
		times = set.getString("Readings.Times");
		soundFilePath = set.getString("Readings.SoundFile");
		status = set.getString("Readings.Status");
		isVideo = set.getBoolean("Readings.IsVideo");		
		//checkedOut = set.getBoolean("Readings.CheckedOut");
		//checkOutTime = set.getTime("Readings.CheckoutTime");
		
		highestIdProcessed = set.getInt("Readings.HighestIdProcessed");
		adjustedWordIds = set.getString("Readings.AdjustedWordIds");
		
		source = set.getString("Readings.Source");
		
		//checkedWords = set.getString("Readings.CheckedWords");
		loaded = true;
		//checkedOut = set.getBoolean("Readings.CheckedOut");
		/*System.out.println("checkedOut" + checkedOut);
		if (checkedOut != null){
			hasTranslation = true;
			if (checkedOut){
				Date checkoutTime = set.getDate("TranslatedReading.CheckoutTime");
				if (VersionControlUtil.hasCheckoutExpired(checkoutTime)){
					checkedOut = false;
				}
			}
		}
		System.out.println("hasTranslation" +hasTranslation);
		
		userId = set.getString("TranslatedReading.UserId");
		loaded = true;*/
		
	}
	
	
	
	
	public static void main(String[] args) {
		//String paragraph = "<p>U.S. Ch&egrave;re Maman, cher Papa;</p><p>Me voil&agrave; install&eacute;e &agrave; Montpellier! J'habite avec une famille tr&egrave;s gentille: Jacques et Marie Trapet et leurs enfants, Cecile et Juliette. Je trouve leur maison tr&egrave;s belle, mais ils ne sont pas contents et ils cherchent une autre maison &agrave; la campagne, avec des chambres individuelles pour les enfants. Nous sommes tr&egrave;s occup&eacute;s ici.</p>";
		//String paragraph = "<p>Le Voyage du Horla</p><p><span id=\"s0\">J'avais reçu, <p>l'<span class=\"linked\">usine</span> Making money is never easy but on the South Pacific island of Yap it used to be very dangerous, difficult work!</p> " +
				//"<p>Although the Yapese people usually spend dollars, their traditional money, the Rai, is actually made of stone. Measuring up to 3.6 metres in diameter, and weighing up to 4 tonnes, this disk-shaped \"stone money\" is still used for weddings and the sale of land.</p>";
		Reading reading = new ReadingImpl("21");  
		String wordWrapped = reading.getWordWrappedReading();
		System.out.println(wordWrapped);
		//preparer.prepare(paragraph, "w");
	}

}